﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Entidad;
using SegIdenPC.Herramientas;
using log4net;
using GS1.Utilitario;
using System.Drawing.Imaging;
using System.Configuration;

namespace SegIdenPC.Formularios
{
    public partial class frmGestionInventario : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmGestionInventario));

        private const string TITULO = "Generar Inventarios";
        private const string FORMATO_TOTAL_ENCONTRADOS = "Total inventarios encontrados: {0}";

        public enum OperacionMantenimiento
        {
            Nuevo,
            Editar
        }
        private OperacionMantenimiento tipoOperacion = OperacionMantenimiento.Nuevo;

        private enum Opcion
        {
            Abrir = 0,
            Nuevo = 1,
            Editar = 2,
            Grabar = 3,
            Generar = 5
        }
        private Inventario inventarioActual = null;
        private ListaTienda listaTienda = null;
        private ListaInventario listaInventario = null;
        private Tienda tiendaActual = null;
        #endregion

        #region --- Constructor ---
        public frmGestionInventario()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmGestionInventario_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }
        private void frmGestionInventario_FormClosing(object sender, FormClosingEventArgs e)
        {
            finalizarFormulario();
        }
        private void tbtnAbrir_Click(object sender, EventArgs e)
        {
            abrir();
        }
        private void tbtnGrabar_Click(object sender, EventArgs e)
        {
            grabar();
        }
        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        private void tbtnEditar_Click(object sender, EventArgs e)
        {
            editar();
        }
        private void btnBuscar_Click(object sender, EventArgs e)
        {
            buscarInventario();
        }
        private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (!e.TabPage.Enabled) { e.Cancel = true; }
        }
        private void btnBuscarTienda_Click(object sender, EventArgs e)
        {
            elegirTienda();
        }

        private void cboEstado_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        private void tbtnNuevo_Click(object sender, EventArgs e)
        {
            if (this.tabPagListado.Enabled)
            {
                // Estableciendo estado de TagPage de Listado y datos
                this.tabPagListado.Enabled = false;
                this.tabPagDatos.Enabled = true;

                // Mostrar la segunda pagina del TabControl
                this.tabControl.SelectedIndex = 1;

                // Estableciendo los estados de los botones
                cambiarEstadoBotones(Opcion.Nuevo);
            }
            if (this.tabPagDatos.Enabled)
            {
                // Estableciendo estado de TagPage de Listado y datos
                this.tabPagListado.Enabled = false;
                this.tabPagDatos.Enabled = true;

                // Mostrar la segunda pagina del TabControl
                this.tabControl.SelectedIndex = 1;
                nuevo();
            }
        }

        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            ListaGeneral listaTipoInventario = null;
            ListaGeneral listaEstado = null;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Activaciones de botones por rol
                controlBotonesPorRol();

                // Instanciando y creando listado de tipos de inventario
                listaTipoInventario = new ListaGeneral();
                listaTipoInventario.Add(new General { codigo = Constantes.CODIGO_TIPO_INVENTARIO_NORMAL, descripcion = Constantes.DESCRIPCION_TIPO_INVENTARIO_NORMAL });
                listaTipoInventario.Add(new General { codigo = Constantes.CODIGO_TIPO_INVENTARIO_CICLICO, descripcion = Constantes.DESCRIPCION_TIPO_INVENTIARIO_CICLICO });

                // Instanciando y creando listado de estado
                listaEstado = new ListaGeneral();
                listaEstado.Add(new General { codigo = Constantes.ESTADO_CODIGO_ACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_ACTIVO });
                listaEstado.Add(new General { codigo = Constantes.ESTADO_CODIGO_INACTIVO, descripcion = Constantes.ESTADO_DESCRIPCION_INACTIVO });


                //Instanciando y creando listado de tiendas
                listaTienda = new ListaTienda();

                // Desactivando el grupo de campo de informacion
                this.tabPagDatos.Enabled = false;
                // Estableciendo Ficha 0 como seleccion incial
                this.tabControl.SelectedIndex = 0;
                // Capturando evento selecting en el control Tab
                this.tabControl.Selecting += new TabControlCancelEventHandler(tabControl_Selecting);

                // Estableciendo a 0 el texto del total de registros encontrados.
                this.lblTotalInventarios.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, 0);

                // Desactivando el boton abrir.
                this.tbtnAbrir.Enabled = false;

                // Estableciendo datos del combo Estado
                this.cboEstado.DataSource = listaEstado;
                this.cboEstado.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboEstado.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboEstado.SelectedIndex = 0;

                // Estableciendo parametros del Combo Tipo Inventario
                this.cboTipoInventario.DataSource = listaTipoInventario;
                this.cboTipoInventario.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboTipoInventario.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboTipoInventario.SelectedIndex = 0;

                //Estableciendo lista de tiendas
                cargarTiendas();

                // Estableciendo tienda actual

                this.tiendaActual = ParametrosAplicacion.TIENDA_ACTUAL;
                this.txtTiendaCodigo.Text = this.tiendaActual.codigo;
                this.txtTiendaDescripcion.Text = this.tiendaActual.nombre;

                // Estableciendo focus
                this.cboCriterio.Focus();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }

        }

        private void cargarTiendas()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_TIENDAS;

            operacion.tienda = new Tienda();
            operacion.tienda.nombre = "%";
            operacion.tienda.estado = Constantes.ESTADO_CODIGO_ACTIVO;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de ListaTienda
            this.listaTienda = contenidoXML.DeserializarTo<ListaTienda>();

            // Estableciendo listado de Tienda
            this.cboCriterio.DataSource = this.listaTienda.lista;
            this.cboCriterio.ValueMember = "codigo";
            this.cboCriterio.DisplayMember = "nombre";
            this.cboCriterio.SelectedIndex = 0;

            // Creando listado para registro de Tienda
            ListaTienda listaTiendaNueva = new ListaTienda();

            foreach (Tienda tienda in this.listaTienda.lista)
            {
                listaTiendaNueva.add(new Tienda { codigo = tienda.codigo, nombre = tienda.nombre });
            }

        }

        private void finalizarFormulario()
        {
            this.tabControl.Selecting -= new TabControlCancelEventHandler(tabControl_Selecting);
        }

        private void controlBotonesPorRol()
        {
            if (ParametrosAplicacion.ROL_ADMINISTRADOR.codigo.Equals(ParametrosAplicacion.USUARIO_ACTUAL.rol.codigo)) { return; }

            this.tbtnNuevo.Visible = false;
            this.tbtnEditar.Visible = false;
            //this.tbtnEliminar.Visible = false;
            this.tbtnGrabar.Visible = false;
        }

        private void elegirTienda()
        {
            using (frmMantTienda frmMantTienda = new frmMantTienda())
            {
                frmMantTienda.formularioBusqueda = true;
                if (frmMantTienda.ShowDialog() == DialogResult.Cancel) { return; }

                this.tiendaActual = frmMantTienda.tiendaActual;
                this.txtTiendaCodigo.Text = this.tiendaActual.codigo;
                this.txtTiendaDescripcion.Text = this.tiendaActual.nombre;
            }
        }

        private void nuevo()
        {
            // Activando grupo para modificar campos
            this.grpDatos.Enabled = true;
            this.tbtnGrabar.Enabled = true;

            // Limpiando los datos del formulario
            this.txtCodigo.Text = string.Empty;
            this.txtTiendaCodigo.Text = string.Empty;
            this.txtTiendaDescripcion.Text = string.Empty;
            this.txtNroReferencia.Text = string.Empty;
            this.txtObservacion.Text = string.Empty;

            // Estableciendo focus al boton buscar tienda origen
            this.cboTipoInventario.Focus();
        }
        private void grabar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarExistenciaInventario()) { return; }

                if (validarEntrada()) { return; }

                // Solicitar confirmacion
                if (!Libreria.ShowMessageboxPregunta("¿Estas seguro de registrar el Inventario?", TITULO)) { return; }

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();

                operacion.inventario = new Inventario();

                // Estableciendo tienda de registro
                operacion.inventario.tienda = new Tienda();
                operacion.inventario.tienda.codigo = this.tiendaActual.codigo;
                operacion.inventario.tienda.nombre = this.tiendaActual.nombre;

                operacion.inventario.tipo = this.cboTipoInventario.SelectedValue.ToString();
                operacion.inventario.nroReferencia = this.txtNroReferencia.Text;
                operacion.inventario.observacion = this.txtObservacion.Text;
                operacion.inventario.estado = this.cboEstado.SelectedValue.ToString();
                operacion.inventario.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                //operacion.inventario.fechaInicio = this.dtpFechaInicio.Value.ToString(Constantes.FORMATO_FECHAHORA);
                //operacion.inventario.fechaFin = this.dtpFechaFin.Value.ToString(Constantes.FORMATO_FECHAHORA);

                // Estableciendo usuario de registro
                operacion.inventario.usuario = new Usuario();
                operacion.inventario.usuario.codUsuario = ParametrosAplicacion.USUARIO_ACTUAL.codUsuario;

                operacion.numero = Constantes.OPERACION_REGISTRAR_INVENTARIO;

                if (tipoOperacion == OperacionMantenimiento.Nuevo)
                {
                    operacion.inventario.codInventario = Constantes.VALOR_CERO;
                    operacion.numero = Constantes.OPERACION_REGISTRAR_INVENTARIO;
                }
                else if (tipoOperacion == OperacionMantenimiento.Editar)
                {
                    operacion.inventario.codInventario = this.txtCodigo.Text;
                    operacion.numero = Constantes.OPERACION_MODIFICAR_INVENTARIO;//Por crear
                }

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    this.txtCodigo.Text = operacionResultado.codigoGenerado;
                    Libreria.ShowMessageboxInfo("Registro guardado correctamente", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se guardo los datos", TITULO);
                    return;
                }

                // Estableciendo los estados de los botones
                this.grpDatos.Enabled = false;

                // Estableciendo estado de TagPage de Listado y datos
                this.tabPagListado.Enabled = true;
                this.tabPagDatos.Enabled = false;

                // Mostrar la primera pagina del TabControl
                this.tabControl.SelectedIndex = 0;

                // Estableciendo los estados de los botones
                cambiarEstadoBotones(Opcion.Generar);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }
        private bool validarEntrada()
        {
            bool resultado = false;

            this.txtTiendaCodigo.Text = this.txtTiendaCodigo.Text.Trim();
            this.txtNroReferencia.Text = this.txtNroReferencia.Text.Trim();
            this.txtObservacion.Text = this.txtObservacion.Text.Trim();

            if (this.txtTiendaCodigo.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtTiendaCodigo, "Debe seleccionar una Tienda", TITULO);
                return true;
            }

            if (this.cboTipoInventario.SelectedIndex == -1)
            {
                Libreria.CampoNecesario(this.cboTipoInventario, "Debe seleccionar un Tipo de Inventario", TITULO);
                return true;
            }

            if (this.txtObservacion.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtObservacion, "Debe ingresar el campo Observación", TITULO);
                return true;
            }

            return resultado;
        }

        private bool validarExistenciaInventario()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_OBTENER_INVENTARIO;

            operacion.inventario = new Inventario();
            operacion.inventario.tienda = new Tienda();
            operacion.inventario.tienda.codigo = ParametrosAplicacion.TIENDA_ACTUAL.codigo;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return true;
            }

            // Obteniendo Objeto de Inventario
            Inventario inventario = contenidoXML.DeserializarTo<Inventario>();

            if (inventario != null)
            {
                Libreria.ShowMessageboxInfo("Ya existe inventario activo para esta tienda");
                return true;
            }

            return false;
        }

        private void salir()
        {
            this.Close();
        }

        private void buscarInventario()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_LISTAR_INVENTARIO;  // Por crear

            operacion.inventario = new Inventario();
            operacion.inventario.tienda = new Tienda();
            operacion.inventario.tienda.codigo = this.cboCriterio.SelectedValue.ToString();
            operacion.inventario.estado = "";


            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return;
            }

            // Obteniendo Objeto de la lista de solicitudes pendientes de autorizacion
            this.listaInventario = contenidoXML.DeserializarTo<ListaInventario>();

            // Mostrar el total de registros encontrados
            this.lblTotalInventarios.Text = string.Format(FORMATO_TOTAL_ENCONTRADOS, listaInventario.lista.Count);

            // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
            this.dgvListadoInventario.AutoGenerateColumns = false;

            // Se establece la fuente de datos de la grilla
            this.dgvListadoInventario.DataSource = listaInventario.lista;

            // Activando o desactivando boton Abrir
            this.tbtnAbrir.Enabled = listaInventario.lista.Count > 0;

            // Colorear grilla deacuerdo a criterios
            pintarGrilla(dgvListadoInventario);

        }

        private void pintarGrilla(DataGridView grilla)
        {
            ListPersonalizada<Inventario> listaInventario = null;
            listaInventario = (ListPersonalizada<Inventario>)grilla.DataSource;

            if (listaInventario != null)
            {
                for (int i = 0; i < listaInventario.Count; i++)
                {
                    Inventario inventario = listaInventario[i];

                    inventario.estado = inventario.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO) ? Constantes.ESTADO_DESCRIPCION_INACTIVO : Constantes.ESTADO_DESCRIPCION_ACTIVO;
                    inventario.fechaRegistro = Convert.ToDateTime(inventario.fechaRegistro).ToString(Constantes.FORMATO_FECHA);
                    //inventario.fechaVencimiento = Convert.ToDateTime(solicitud.fechaVencimiento).ToString(Constantes.FORMATO_FECHA);
                    grilla.Rows[i].Cells[1].Value = inventario.usuario.nombresyApellidos; //tienda.nombre

                    if (inventario.estado == Constantes.ESTADO_DESCRIPCION_INACTIVO)
                    {
                        this.dgvListadoInventario.Rows[i].DefaultCellStyle.BackColor = Color.FromArgb(255, 128, 128);
                    }
                }
            }
        }

        private void abrir()
        {
            // Estableciendo estado de TagPage de Listado y datos
            this.tabPagListado.Enabled = false;
            this.tabPagDatos.Enabled = true;

            // Mostrar la segunda pagina del TabControl
            this.tabControl.SelectedIndex = 1;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Abrir);

            // Valida si seleccione algun equipos
            if (this.dgvListadoInventario.CurrentRow != null && this.dgvListadoInventario.CurrentRow.Index > -1)
            {
                ListPersonalizada<Inventario> listaInventario = (ListPersonalizada<Inventario>)this.dgvListadoInventario.DataSource;
                this.inventarioActual = obtenerInventario(listaInventario[this.dgvListadoInventario.CurrentRow.Index]);
                this.txtCodigo.Text = inventarioActual.codInventario;

                this.tiendaActual = inventarioActual.tienda;
                this.txtTiendaCodigo.Text = inventarioActual.tienda.codigo.ToString();
                this.txtTiendaDescripcion.Text = inventarioActual.tienda.nombre;

                this.txtObservacion.Text = inventarioActual.observacion;

                this.txtNroReferencia.Text = inventarioActual.nroReferencia;

                this.cboTipoInventario.Text = inventarioActual.tipo.ToString();

                switch (inventarioActual.estado)
                {
                    case Constantes.ESTADO_CODIGO_ACTIVO:
                        this.cboEstado.Text = Constantes.ESTADO_DESCRIPCION_ACTIVO;
                        break;
                    case Constantes.ESTADO_CODIGO_INACTIVO:
                        this.cboEstado.Text = Constantes.ESTADO_DESCRIPCION_INACTIVO;
                        break;
                }

                switch (inventarioActual.tipo)
                {
                    case Constantes.CODIGO_TIPO_INVENTARIO_NORMAL:
                        this.cboTipoInventario.Text = Constantes.DESCRIPCION_TIPO_INVENTARIO_NORMAL;
                        break;
                    case Constantes.CODIGO_TIPO_INVENTARIO_CICLICO:
                        this.cboTipoInventario.Text = Constantes.DESCRIPCION_TIPO_INVENTIARIO_CICLICO;
                        break;
                }
                //se deshabilitan todos los botones
                habilitarBotones(false);
            }
        }

        private void habilitarBotones(Boolean activar)
        {
            if (activar)
            {
                this.cboEstado.Enabled = true;
                this.btnBuscarTienda.Enabled = true;
                this.txtObservacion.Enabled = true;
                this.txtNroReferencia.Enabled = true;
                this.cboTipoInventario.Enabled = true;

            }
            else
            {
                this.cboEstado.Enabled = false;
                this.btnBuscarTienda.Enabled = false;
                this.txtObservacion.Enabled = false;
                this.txtNroReferencia.Enabled = false;
                this.cboTipoInventario.Enabled = false;
            }
        }

        private void cambiarEstadoBotones(Opcion tipoOpcion)
        {

            switch (tipoOpcion)
            {
                case Opcion.Abrir:
                    this.tbtnEditar.Enabled = true;
                    this.tbtnNuevo.Enabled = true;
                    this.tbtnSalir.Enabled = true;

                    this.tbtnAbrir.Enabled = false;
                    this.tbtnGrabar.Enabled = false;
                    break;
                case Opcion.Nuevo:
                    this.tbtnGrabar.Enabled = true;
                    this.tbtnSalir.Enabled = true;

                    this.tbtnNuevo.Enabled = false;
                    this.tbtnAbrir.Enabled = false;
                    this.tbtnEditar.Enabled = false;
                    break;
                case Opcion.Editar:
                    this.tbtnGrabar.Enabled = true;
                    this.tbtnSalir.Enabled = true;

                    this.tbtnEditar.Enabled = false;
                    this.tbtnNuevo.Enabled = false;
                    this.tbtnAbrir.Enabled = false;
                    break;
                case Opcion.Grabar:
                    this.tbtnNuevo.Enabled = true;
                    this.tbtnEditar.Enabled = true;
                    this.tbtnSalir.Enabled = true;

                    this.tbtnGrabar.Enabled = false;
                    this.tbtnAbrir.Enabled = false;
                    break;

                case Opcion.Generar:
                    this.tbtnAbrir.Enabled = true;
                    this.tbtnNuevo.Enabled = true;
                    this.tbtnSalir.Enabled = true;

                    this.tbtnGrabar.Enabled = false;
                    this.tbtnEditar.Enabled = false;
                    break;
            }
        }

        private Inventario obtenerInventario(Inventario inventario)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            // Estableciendo operacion a ser enviada al Servicio REST
            operacion = new Operacion();
            operacion.numero = Constantes.OPERACION_OBTENER_INVENTARIO;
            operacion.inventario = inventario;

            // Instanciando y ejecutando llamada al ServicioREST
            ConexionREST conexionREST = new ConexionREST();
            contenidoXML = conexionREST.ejecutarOperacion(operacion);

            // Obteniendo Objeto de Error
            OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

            // Validar si hay error
            if (operacionError != null)
            {
                Libreria.ShowMessageboxError(operacionError.descripcion);
                return inventario;
            }

            // Obteniendo Objeto de Producto
            Inventario inventarioObtenido = contenidoXML.DeserializarTo<Inventario>();

            return inventarioObtenido;

        }

        private void editar()
        {
            //se habilitan todos los botones
            habilitarBotones(true);

            //No cambia la tienda solicitante
            this.btnBuscarTienda.Enabled = false;

            // Estableciendo los estados de los botones
            cambiarEstadoBotones(Opcion.Editar);

            tipoOperacion = OperacionMantenimiento.Editar;
        }


        #endregion

        private void cboTipoInventario_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void txtTiendaCodigo_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
